/*
 * @Date         : 2024-05-12 17:44:11 星期0
 * @Author       : xut
 * @Description  :
 */
import grpc from "@grpc/grpc-js"

export const echoServiceImpl = {
  unaryEcho: (call, cb) => {
    let isCancelled = false

    // request header 接收
    const incomingTimestamps = call.metadata.get("timestamp")

    if (incomingTimestamps.length > 0) {
      console.log("Timestamp from metadata:")
      for (const [index, value] of incomingTimestamps.entries()) {
        console.log(` ${index}. ${value}`)
      }
    }

    // response header 响应
    const responseHeaderMetadata = new grpc.Metadata()
    responseHeaderMetadata.set("timestamp", new Date().toISOString())
    call.sendMetadata(responseHeaderMetadata)

    // response trailers 响应
    const responseTrailerMetadata = new grpc.Metadata()
    responseTrailerMetadata.set("timestamp", new Date().toISOString())

    // 当客户调用 cancel() 后，服务端 'cancelled' 事件将被触发
    call.on("cancelled", () => {
      isCancelled = true
      console.log("server received cancelled event")
    })

    setTimeout(() => {
      if (isCancelled) return
      // 即使继续执行，调用 cb 客户端也无法接收，因为 cancelled 事件后会主动关闭连接
      console.log("server execute")
      const response = { value: "Hello " + call.request.name }
      cb(null, response, responseTrailerMetadata)
    }, 5000)
  },

  serverStreamingEcho: (call) => {
    let isCancelled = false
    // request header 接收
    const incomingTimestamps = call.metadata.get("timestamp")

    if (incomingTimestamps.length > 0) {
      console.log("Timestamp from metadata:")
      for (const [index, value] of incomingTimestamps.entries()) {
        console.log(` ${index}. ${value}`)
      }
    }

    // response header 响应
    const responseHeaderMetadata = new grpc.Metadata()
    responseHeaderMetadata.set("timestamp", new Date().toISOString())
    call.sendMetadata(responseHeaderMetadata)

    // 当客户调用 cancel() 后，服务端 'cancelled' 事件将被触发
    call.on("cancelled", () => {
      isCancelled = true
      console.log("server received cancelled event")
    })

    const hello = "Hello From Server"

    for (let i = 0; i < hello.length; i++) {
      if (isCancelled) return
      call.write({ value: hello[i] })
    }

    // response trailers 响应
    const responseTrailerMetadata = new grpc.Metadata()
    responseTrailerMetadata.set("timestamp", new Date().toISOString())
    call.end(responseTrailerMetadata)
  },
}
